// fiber_echo_server.cpp
#include <boost/fiber/all.hpp>
#include <boost/asio.hpp>
#include <iostream>
#include <memory>
#include <vector>

using namespace boost::asio;
using namespace boost::asio::ip;

class EchoSession : public std::enable_shared_from_this<EchoSession> {
private:
    tcp::socket socket_;
    std::array<char, 1024> buffer_;

public:
    explicit EchoSession(tcp::socket socket) : socket_(std::move(socket)) {}

    void start() {
        // 为每个会话创建一个 fiber
        boost::fibers::fiber([self = shared_from_this()]() {
            self->do_echo();
        }).detach();
    }

private:
    void do_echo() {
        try {
            std::cout << "Client connected from " 
                      << socket_.remote_endpoint() << std::endl;

            while (true) {
                // 使用 fiber 的异步操作
                boost::system::error_code ec;
                size_t length = socket_.async_read_some(
                    boost::asio::buffer(buffer_),
                    boost::fibers::asio::yield[ec]
                );

                if (ec == boost::asio::error::eof) {
                    std::cout << "Client disconnected" << std::endl;
                    break;
                } else if (ec) {
                    std::cerr << "Read error: " << ec.message() << std::endl;
                    break;
                }

                std::cout << "Received: " << std::string(buffer_.data(), length) << std::endl;

                // 回显数据
                boost::asio::async_write(
                    socket_,
                    boost::asio::buffer(buffer_, length),
                    boost::fibers::asio::yield[ec]
                );

                if (ec) {
                    std::cerr << "Write error: " << ec.message() << std::endl;
                    break;
                }
            }
        } catch (const std::exception& e) {
            std::cerr << "Exception in session: " << e.what() << std::endl;
        }
    }
};

class EchoServer {
private:
    io_context& io_context_;
    tcp::acceptor acceptor_;

public:
    EchoServer(io_context& io_context, short port)
        : io_context_(io_context),
          acceptor_(io_context, tcp::endpoint(tcp::v4(), port)) {
        start_accept();
    }

private:
    void start_accept() {
        acceptor_.async_accept(
            boost::fibers::asio::yield,
            [this](boost::system::error_code ec, tcp::socket socket) {
                if (!ec) {
                    std::make_shared<EchoSession>(std::move(socket))->start();
                } else {
                    std::cerr << "Accept error: " << ec.message() << std::endl;
                }
                // 继续接受新连接
                start_accept();
            }
        );
    }
};

int main() {
    try {
        io_context io_context;
        
        // 初始化 fiber 的异步 I/O 支持
        boost::fibers::use_scheduling_algorithm<boost::fibers::asio::round_robin>(io_context);
        
        EchoServer server(io_context, 8080);
        std::cout << "Echo server started on port 8080" << std::endl;
        
        // 运行 io_context（这也会运行 fiber 调度器）
        io_context.run();
        
    } catch (std::exception& e) {
        std::cerr << "Exception: " << e.what() << std::endl;
    }
    
    return 0;
}